/**
* ============================================
* @author:syf20020816@outlook.com
* @since:20230906
* @version:0.0.1
* @type:interface
* @description:
* # SInput
* This is a basic input box, often used in forms, divided into two types: text and password
* ## properties:
* - in property <int> font-weight : font weight for input
* - in property <string> placeholder: default placeholder which you wanna show when no text
* - in property <Themes> theme: Surrealism themes
* - in property <length> input-width: Please do not use width to adjust the length of the input box , use this property to instead
* - in property <length> font-size: font size 
* - in property <bool> disabled: can input be edited
* - in property <bool> clearable: can input be cleared
* - in property <bool> password: can the password input display the password
* - out property <bool> has-focus : input is focused or not
* - private property <brush> placeholder-color : placeholder color
* - in-out property <InputType> type : input type (text or password)
* - in-out property <brush> font-color : font color
* - in-out property <brush> icon-color : icon color
* - in-out property <string> text : the text of the input
* ## functions:
* - pure public function get() ->string : get text
* - public function set(text:string) : set text
* - public function clear() : clear text
* - public function select-all() : select all 
* - public function clear-selection() : clears the selection
* - public function cut() : copies the selected text to the clipboard and removes it from the editable area
* - public function copy() : copies the selected text to the clipboard
* - public function paste() : pastes the text text of the clipboard at the cursor position
* ## callbacks:
* - callback accepted(string) : run when pressed down enter key
* - callback changed(string) : run when text changed
* ============================================
*/
import {ROOT_STYLES,DefaultSInputProps} from "../../themes/index.slint";
import {SText } from "../text/index.slint";
import {SIcon} from "../icon/index.slint";
import { Themes,UseIcons } from "../../use/index.slint";
import { SCard } from "../card/index.slint";

export component Input inherits SCard {
  card-height: DefaultSInputProps.card-height;
  min-width: 160px;   
  card-width: DefaultSInputProps.card-width;
  clip: false;
  border-type: DefaultSInputProps.border-type;
  shadow-type: DefaultSInputProps.shadow-type;
  padding-type: DefaultSInputProps.padding-type;
  vertical-stretch: 0;
  horizontal-stretch: 1;
  font-color: DefaultSInputProps.font-color;
  font-size: DefaultSInputProps.font-size;
  font-weight: DefaultSInputProps.font-weight;
  font-family: DefaultSInputProps.font-family;
  font-italic: DefaultSInputProps.font-italic;
  theme: DefaultSInputProps.theme;
  in property <string> placeholder : DefaultSInputProps.placeholder;
  in property <bool> disabled: DefaultSInputProps.disabled;
  in property <bool> clearable:DefaultSInputProps.clearable;
  //use eye-icon
  in property <bool> password:DefaultSInputProps.password;
  out property <bool> has-focus<=>input.has-focus;
  private property <brush> placeholder-color;
  in-out property <InputType> type : password? InputType.password:InputType.text;
  in-out property <brush> icon-color;
  in-out property <string> text <=> input.text;
  callback accepted(string);
  callback changed(string);
  //functions
  pure public function get() ->string{
    self.text
  }
  public function set(text:string) {
    self.text = text
  }
  public function clear() {
    root.text = "";
  }
  public function select-all() {
    input.select-all();
  }

  public function clear-selection() {
    input.clear-selection();
  }

  public function cut() {
    input.cut();
  }

  public function copy() {
    input.copy();
  }

  public function paste() {
    input.paste();
  }
    states [
      light when root.theme == Themes.Light: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.light.opacity : ROOT-STYLES.sur-theme-colors.light.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.light.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.light.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.light.font;
        icon-color : ROOT-STYLES.sur-theme-colors.light.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.light.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.light.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.light.deepest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.light.deepest;
      }
      primary when root.theme == Themes.Primary: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.primary.opacity : ROOT-STYLES.sur-theme-colors.primary.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.primary.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.primary.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.primary.font;
        icon-color : ROOT-STYLES.sur-theme-colors.primary.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.primary.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.primary.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.primary.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.primary.weakest;
      }
      success when root.theme == Themes.Success: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.success.opacity:ROOT-STYLES.sur-theme-colors.success.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.success.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.success.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.success.font;
        icon-color: ROOT-STYLES.sur-theme-colors.success.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.success.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.success.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.success.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.success.weaker;
      }
      info when root.theme == Themes.Info: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.info.opacity:ROOT-STYLES.sur-theme-colors.info.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.info.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.info.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.info.font;
        icon-color: ROOT-STYLES.sur-theme-colors.info.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.info.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.info.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.info.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.info.weaker;
      }
      warning when root.theme == Themes.Warning: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.warning.opacity:ROOT-STYLES.sur-theme-colors.warning.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.warning.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.warning.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.warning.font;
        icon-color: ROOT-STYLES.sur-theme-colors.warning.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.warning.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.warning.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.warning.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.warning.weaker;
      }
      error when root.theme == Themes.Error: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.error.opacity:ROOT-STYLES.sur-theme-colors.error.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.error.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.error.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.error.font;
        icon-color: ROOT-STYLES.sur-theme-colors.error.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.error.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.error.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.error.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.error.weaker;
      }
      dark when root.theme == Themes.Dark: {
        root.background : !input.has-focus?ROOT-STYLES.sur-theme-colors.dark.opacity:ROOT-STYLES.sur-theme-colors.dark.normal;
        root.border-color: ROOT-STYLES.sur-theme-colors.dark.deeper;
        root.drop-shadow-color: ROOT-STYLES.sur-theme-colors.dark.deepest;
        font-color: ROOT-STYLES.sur-theme-colors.dark.font;
        icon-color: ROOT-STYLES.sur-theme-colors.dark.font;
        input.selection-background-color : ROOT-STYLES.sur-theme-colors.dark.normal;
        input.selection-foreground-color : ROOT-STYLES.sur-theme-colors.dark.font;
        hight-light.background : !input.has-focus?transparent:ROOT-STYLES.sur-theme-colors.dark.weakest;
        root.placeholder-color : ROOT-STYLES.sur-theme-colors.dark.weaker;
      }
    ]

    view := HorizontalLayout {
      padding-left: root.padding-left;
      padding-right: root.padding-right;

      input-view:= Rectangle {
        clip: true;
        if root.text=="" :i-placeholder := SText { 
          theme: root.theme;
          text: root.placeholder;
          color: root.placeholder-color;
          font-size: root.font-size;
          font-weight: root.font-weight;
          font-italic: root.font-italic;
          font-family: root.font-family;
          width: input.width - input.font-size;
          wrap: no-wrap;
          overflow: elide;
        }

        input := TextInput {
          property <length> computed_x;
          property <length> padding-outer: view.padding-left + view.padding-right;
          x: min(0px, max(parent.width - self.width, self.computed_x));
          width: max(parent.width, self.preferred-width);
          height: ROOT-STYLES.sur-font.font-size * 2;
          color: root.font-color;
          horizontal-alignment: left;
          vertical-alignment: center;
          font-size: root.font-size;
          font-weight: root.font-weight;
          font-italic: root.font-italic;
          font-family: root.font-family;
          read-only: root.disabled;
          single-line: true;
          input-type: root.type;
          wrap: no-wrap;
          accepted => {
            root.accepted(root.text)
          }
          edited => {
            root.changed(root.text)
          }

          cursor-position-changed(cpos) => {
            if (cpos.x + self.computed_x < self.padding-outer) {
              self.computed_x = - cpos.x + self.padding-outer;
            } else if (cpos.x + self.computed_x > parent.width - self.padding-outer) {
              self.computed_x = parent.width - cpos.x - self.padding-outer;
            }
          }
        }
      }
      if root.password: eye-icon:= Rectangle{
        eye:=SIcon {
          colorize: self.get-colorize();
          theme: root.theme;
          source: root.type == InputType.password ? UseIcons.icons.Preview-close : UseIcons.icons.Preview-open;
          height: root.font-size;
          width: root.font-size;
          clicked => {
            if(self.source==UseIcons.icons.Preview-close){
              root.type = InputType.text;
              self.source = UseIcons.icons.Preview-open
            }else{
              root.type = InputType.password;
              self.source = UseIcons.icons.Preview-close
            }
          }
        }
      }
      if root.clearable:clear-icon:= Rectangle {
        SIcon{
          colorize: self.get-colorize();
          height: root.font-size;
          width: root.font-size;
          theme: root.theme;
          source: UseIcons.icons.Close-one;
          clicked => {
            root.clear();
          }
        }
      }
  }

  hight-light:= Rectangle {
    y: root.height - self.height  * 2;
    height: 2px;
    width : !input.has-focus? 0px:view.width - view.padding-left - view.padding-right;
    border-radius: 1px;
    animate width {
      duration: ROOT-STYLES.sur-an-duration;
      easing: ROOT-STYLES.sur-an-easing;
    }
  }
}
